﻿// --------------------------------------------------------------------------------------------------------------------
// <copyright file="Status.cs" company="XamlNinja">
//   2011 Richard Griffin and Ollie Riches
// </copyright>
// <summary>
//   Common response status codes.
// </summary>
// --------------------------------------------------------------------------------------------------------------------

namespace WP7Contrib.Communications
{
    using System;
    using Common;

    /// <summary>
    /// Common response status codes.
    /// </summary>
    public sealed class Status : BaseModel,  IEquatable<Status>
    {
        /// <summary>
        /// The continue.
        /// </summary>
        public static Status Continue = new Status(100);

        /// <summary>
        /// The switching protocols.
        /// </summary>
        public static Status SwitchingProtocols = new Status(101);

        /// <summary>
        /// The ok.
        /// </summary>
        public static Status OK = new Status(200, "OK");

        /// <summary>
        /// The created.
        /// </summary>
        public static Status Created = new Status(201);

        /// <summary>
        /// The accepted.
        /// </summary>
        public static Status Accepted = new Status(202);

        /// <summary>
        /// The non authoritative information.
        /// </summary>
        public static Status NonAuthoritativeInformation = new Status(203);

        /// <summary>
        /// The no content.
        /// </summary>
        public static Status NoContent = new Status(204);

        /// <summary>
        /// The reset content.
        /// </summary>
        public static Status ResetContent = new Status(205);

        /// <summary>
        /// The partial content.
        /// </summary>
        public static Status PartialContent = new Status(206);

        /// <summary>
        /// The ambiguous.
        /// </summary>
        public static Status Ambiguous = new Status(300);

        /// <summary>
        /// The moved.
        /// </summary>
        public static Status Moved = new Status(301);

        /// <summary>
        /// The redirect.
        /// </summary>
        public static Status Redirect = new Status(302);

        /// <summary>
        /// The redirect method.
        /// </summary>
        public static Status RedirectMethod = new Status(303);

        /// <summary>
        /// The not modified.
        /// </summary>
        public static Status NotModified = new Status(304);

        /// <summary>
        /// The use proxy.
        /// </summary>
        public static Status UseProxy = new Status(305);

        /// <summary>
        /// The redirect keep verb.
        /// </summary>
        public static Status RedirectKeepVerb = new Status(307);

        /// <summary>
        /// The bad request.
        /// </summary>
        public static Status BadRequest = new Status(400);

        /// <summary>
        /// The unauthorized.
        /// </summary>
        public static Status Unauthorized = new Status(401);

        /// <summary>
        /// The forbidden.
        /// </summary>
        public static Status Forbidden = new Status(403);

        /// <summary>
        /// The not found.
        /// </summary>
        public static Status NotFound = new Status(404);

        /// <summary>
        /// The method not allowed.
        /// </summary>
        public static Status MethodNotAllowed = new Status(405);

        /// <summary>
        /// The not acceptable.
        /// </summary>
        public static Status NotAcceptable = new Status(406);

        /// <summary>
        /// The proxy authentication required.
        /// </summary>
        public static Status ProxyAuthenticationRequired = new Status(407);

        /// <summary>
        /// The request timeout.
        /// </summary>
        public static Status RequestTimeout = new Status(408);

        /// <summary>
        /// The conflict.
        /// </summary>
        public static Status Conflict = new Status(409);

        /// <summary>
        /// The gone.
        /// </summary>
        public static Status Gone = new Status(410);

        /// <summary>
        /// The length required.
        /// </summary>
        public static Status LengthRequired = new Status(411);

        /// <summary>
        /// The precondition failed.
        /// </summary>
        public static Status PreconditionFailed = new Status(412);

        /// <summary>
        /// The request entity too large.
        /// </summary>
        public static Status RequestEntityTooLarge = new Status(413);

        /// <summary>
        /// The request uri too long.
        /// </summary>
        public static Status RequestUriTooLong = new Status(414);

        /// <summary>
        /// The unsupported media type.
        /// </summary>
        public static Status UnsupportedMediaType = new Status(415);

        /// <summary>
        /// The requested range not satisfiable.
        /// </summary>
        public static Status RequestedRangeNotSatisfiable = new Status(416);

        /// <summary>
        /// The expectation failed.
        /// </summary>
        public static Status ExpectationFailed = new Status(417);

        /// <summary>
        /// The internal server error.
        /// </summary>
        public static Status InternalServerError = new Status(500);

        /// <summary>
        /// The not implemented.
        /// </summary>
        public static Status NotImplemented = new Status(501);

        /// <summary>
        /// The bad gateway.
        /// </summary>
        public static Status BadGateway = new Status(502);

        /// <summary>
        /// The service unavailable.
        /// </summary>
        public static Status ServiceUnavailable = new Status(503);

        /// <summary>
        /// The gateway timeout.
        /// </summary>
        public static Status GatewayTimeout = new Status(504);

        /// <summary>
        /// The http version not supported.
        /// </summary>
        public static Status HttpVersionNotSupported = new Status(505);

        /// <summary>
        /// Gets Code.
        /// </summary>
        public int Code { get; private set; }

        /// <summary>
        /// Gets Description.
        /// </summary>
        public string Description { get; private set; }

        /// <summary>
        /// Initializes a new instance of the <see cref="Status"/> struct.
        /// </summary>
        /// <param name="code">
        /// The code.
        /// </param>
        public Status(int code)
        {
            this.Code = code;
        }

        /// <summary>
        /// Initializes a new instance of the <see cref="Status"/> class. 
        /// </summary>
        /// <param name="code">
        /// The status code.
        /// </param>
        /// <param name="description">
        /// The status description.
        /// </param>
        public Status(int code, string description)
        {
            this.Code = code;
            this.Description = description;
        }

        /// <summary>
        /// Returns true if the parameter is equal to the current instance, 
        /// </summary>
        /// <param name="status">
        /// An instance to evaluate.
        /// </param>
        /// <returns>
        /// Returns true if the parameter is equal to the current instance.
        /// </returns>
        public bool Equals(Status status)
        {
            if (ReferenceEquals(null, status))
            {
                return false;
            }

            if (this.Code != status.Code)
            {
                return false;
            }

            return true;
        }

        /// <summary>
        /// Returns true if the parameter is equal to the current instance, 
        /// </summary>
        /// <param name="obj">
        /// An object to evaluate.
        /// </param>
        /// <returns>
        /// Returns true if the parameter is equal to the current instance.
        /// </returns>
        public override bool Equals(object obj)
        {
            if (ReferenceEquals(null, obj))
            {
                return false;
            }

            return obj is Status && this.Equals((Status)obj);
        }

        /// <summary>
        /// Calculates thehash code - uses the code and description properties
        /// </summary>
        /// <returns>
        /// Returns the hash code.
        /// </returns>
        public override int GetHashCode()
        {
            return this.CombineHashCodes(this.Code, this.Description);
        }

        /// <summary>
        /// The equals operator.
        /// </summary>
        /// <param name="s1">
        /// s1 instance.
        /// </param>
        /// <param name="s2">
        /// s2 instance.
        /// </param>
        /// <returns>
        /// Returns true if the instances are equal.
        /// </returns>
        public static bool operator ==(Status s1, Status s2)
        {
            return Equals(s1, s2);
        }

        /// <summary>
        /// The not equals to operator
        /// </summary>
        /// <param name="s1">
        /// s1 instance.
        /// </param>
        /// <param name="s2">
        /// s2 instance.
        /// </param>
        /// <returns>
        /// Returns true if the instances are not equal.
        /// </returns>
        public static bool operator !=(Status s1, Status s2)
        {
            return !Equals(s1, s2);
        }
    }
}